package com.allen.app.common.utils;

import cn.hutool.core.util.StrUtil;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Description: 排序工具类
 *
 * @author Limiaojun
 * @date 2019/3/15 16:40
 **/
@SuppressWarnings("all")
public class SortUtils {

    /**
     * 排序,支持ListObject 和ListMap 多字段排序
     *
     * @param list
     * @param sortnameArr 排序的字段名称
     * @param typeArr     升序 true 倒序false
     */
    public static <E> void sortList(List<E> list, final String[] sortnameArr, final boolean[] typeArr) {

        if (null != sortnameArr && sortnameArr.length > 0 && sortnameArr.length != typeArr.length) {
            throw new RuntimeException("排序字段和排序方式长度不一致");
        }

        Collections.sort(list, new Comparator<E>() {
            /**
             * 排序
             */
            @Override
            public int compare(E a, E b) {
                int ret = 0;
                try {
                    if (null == sortnameArr || sortnameArr.length == 0) {
                        ret = compareObject(typeArr[0], a, b);
                    } else {
                        for (int i = 0; i < sortnameArr.length; i++) {
                            ret = compareObject(sortnameArr[i], typeArr[i], a, b);
                            if (0 != ret) {
                                break;
                            }
                        }
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
                return ret;
            }
        });
    }

    /**
     * Description:
     *
     * @param sortname
     * @param isAsc
     * @param a
     * @param b
     * @return
     * @throws Exception
     * @author Limiaojun
     * @date 2017年9月28日 下午3:36:16
     */
    private static <E> int compareObject(final String sortname, final boolean isAsc, E a, E b) throws Exception {
        Object v1 = null;
        Object v2 = null;
        if (a instanceof Map && b instanceof Map) {
            v1 = ((Map) a).get(sortname);
            v2 = ((Map) b).get(sortname);
        } else { //
            v1 = Objects.isNull(a) ? null : Jackson.jsonObject(a).get(sortname);
            v2 = Objects.isNull(b) ? null : Jackson.jsonObject(b).get(sortname);
        }
        return compareObject(isAsc, v1, v2);
    }

    /**
     * Description:
     *
     * @param isAsc
     * @param v1
     * @param v2
     * @return
     * @throws Exception
     * @author Limiaojun
     * @date 2017年9月28日 下午3:36:19
     */
    private static <E> int compareObject(final boolean isAsc, E v1, E v2) throws Exception {
        int ret = 0;
        if (null == v1) {
            return 1;
        }
        if (null == v2) {
            return -1;
        }
        if (v1 instanceof Integer && v2 instanceof Integer) {
            Integer o1 = (Integer) v1;
            Integer o2 = (Integer) v2;
            if (isAsc) {
                ret = o1.compareTo(o2);
            } else {
                ret = o2.compareTo(o1);
            }
        } else if (v1 instanceof Date && v2 instanceof Date) {
            Date o1 = (Date) v1;
            Date o2 = (Date) v2;
            if (isAsc) {
                ret = o1.compareTo(o2);
            } else {
                ret = o2.compareTo(o1);
            }
        } else if (v1 instanceof Double && v2 instanceof Double) {
            Double o1 = (Double) v1;
            Double o2 = (Double) v2;
            if (isAsc) {
                ret = o1.compareTo(o2);
            } else {
                ret = o2.compareTo(o1);
            }
        } else if (v1 instanceof Long && v2 instanceof Long) {
            Long o1 = (Long) v1;
            Long o2 = (Long) v2;
            if (isAsc) {
                ret = o1.compareTo(o2);
            } else {
                ret = o2.compareTo(o1);
            }
        }
        return ret;
    }


    public static <E> void sort(List<E> list, String sortField, final boolean isAsc) {

        Collections.sort(list, new Comparator<E>() {
            /**
             * 排序
             */
            @Override
            public int compare(E a, E b) {
                int ret = 0;
                try {
                    if (StrUtil.isBlank(sortField)) {
                        ret = compareObject(isAsc, a, b);
                    } else {
                        Object v1 = Objects.isNull(a) ? null : Jackson.jsonObject(a).get(sortField);
                        Object v2 = Objects.isNull(b) ? null : Jackson.jsonObject(b).get(sortField);
                        ret = compareObject(isAsc, v1, v2);

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return ret;
            }
        });
    }
}
